<template>
	<div>
		<el-alert
			v-if="config && config.allowAdd"
			:title="notice"
			:type="added ? 'success' : 'info'"
			:show-icon="true"
			:closable="true"
			style="margin-bottom:5px">
		</el-alert>
		<el-select ref="select" v-model="currentValue" :multiple="multiple" :remote="remote" :filterable="remote" :remote-method="doQuery" :loading="loading" :placeholder="placeholder" @input="onInput">
			<el-option
				v-for="item in currentOptions"
				:key="item.value"
				:label="item.label"
				:value="item.value">
			</el-option>
		</el-select>
		<i v-if="loading && !adding" class="el-icon-loading"></i>
		<el-button v-if="canAdd | adding" type="primary" icon="plus" :loading="adding" @click="onAdd"></el-button>
		<span v-if="showEmptyNotice">{{emptyNotice}}</span>
	</div>
</template>
<script>

	import Vue from 'vue'
	import ElementUI from 'element-ui'
	import FormUtils from 'winged/utils/wt-form-utils'
	import ModelUtils from '../utils/wt-model-utils'
	import request from '../utils/axios'

	Vue.use(ElementUI);

	const defaultNotice = '输入关键字进行查找，如果该关键词不存在，必须点击"+"按钮收录到数据库才可以使用';

	export default {
		name: 'wt-select',
		props: {
			value: {
				type: [String, Array, Number],
				default: null
			},
			options: {
				type: Array,
				default: function() {
					return null;
				}
			},
			multiple: Boolean,
			query: {
				type: Object,
				default: null
			},
			placeholder: {
				type: String,
				default: ''
			},
			// 当选项列表为空时显示的提示
			emptyNotice: {
				type: String,
				default: null
			},
			paramsData: {
				type: Object,
				default: null
			},
			customLabel: {
				type: Function,
				default: undefined
			},
			//格式化组件传出去的值
			parse: {
				type:Function,
				default:function(data){
					return data
				}
			},
			//格式化组件传入的值
			getCurrentValue: {
				type:Function,
				default:function(data){
					return data
				}
			}
		},
		created(){
			// try {
			// 	this.currentValue = JSON.parse(this.currentValue).map(item => {
			// 		return item[this.tableName]
			// 	})
			// } 
			this.currentValue = this.getCurrentValue(this.currentValue)
		},
		data() {
			return {
				currentValue: this.value,
				currentOptions: this.options ? this.options: null,
				// 用于记录当前搜索结果的keyword
				currentKeyword: null,
				loading: false,
				config: this.query,
				// 是否正在添加关键词
				adding: false,
				// 标记当前关键词是否不存在于列表中（可以被添加收录）
				noItemFound: false,
				// 当前关键词是否已被成功收录
				added: false,
				// 用于强制触发一次load
				doLoad: false,
				originOptions:null
			}
		},
		watch: {
			// 'value'(val, oldValue) {
			// 	this.currentValue = val;
			// }
		},
		computed: {
			remote: function() {
				return this.config !== undefined && this.config != null;
			},
			canAdd: function() {
				return this.config && this.config.allowAdd && this.noItemFound && this.$refs.select && this.currentKeyword != null;
			},
			notice: function() {
				return this.canAdd ? '点击"+"按钮将"' + this.currentKeyword + '"添加到数据库' : (this.added ? '已将"' + this.currentKeyword + '" 收录到数据库' : defaultNotice);
			},
			showEmptyNotice() {
				return !this.canAdd && !this.loading && !(this.currentOptions && this.currentOptions.length > 0) && this.emptyNotice;
			}
		},
		methods: {
			load() {
				if (!this.loading) {
					this.doLoad = true;
					this.doQuery(this.currentKeyword);
				}
			},
			reset() {
				this.currentKeyword = null;
				this.noItemFound = false;
				this.added = false;
				this.doQuery('');
			},
			doQuery(keyword) {
				// 是否实时通过关键字进行查询
				let autoFilter = this.config && this.config.useAutoFilter;
				if (this.doLoad || autoFilter || !this.currentOptions || this.currentOptions.length == 0) {
					this.doLoad = false;
					let params = {};
					if (this.config.pagination) {
						FormUtils.addPaginationParams(params);
					}
					if (autoFilter) {
						params[this.config.filterParam] = keyword;
					}
					ModelUtils.buildQueryExtraParams(this.config, this.paramsData, params);
					let vm = this;
					this.loading = true;
					if(keyword != this.currentKeyword) {
						this.added = false;
					}
					request(this.config.url, this.config.method, params, this.config.transfer, function(data) {
						vm.loading = false;
						vm.originOptions = FormUtils.parseArray(data)
						vm.setQueryResult(keyword, FormUtils.parseArray(data));
					}, function(error) {
						vm.loading = false;
						vm.$message.error('选项加载失败，请稍后重试');
					});
				}
			},
			onInput(val) {
				val = this.parse(val)
				this.$emit('input', val);
			},
			setItem(value) {
				if (this.multiple) {
					this.currentValue.push(value);
				}
				else {
					this.currentValue = value;
				}	
				this.onInput(this.currentValue);
			},
			setQueryResult(keyword, data, setCurrentItem = false) {
				if (data != null) {
					if (keyword != '') {
						this.currentKeyword = keyword;
					}
					if (this.query.resultParam){
						data = data[this.query.resultParam];
					}
					let options = [];
					let foundItem = false;
					let foundValue = null;
					for (let i = 0; i < data.length; i ++) {
						let item = data[i];
						let label = '';
						let value = null;
						if (typeof (item) == 'string') {
							label = item;
							value = label;
						}
						else {
							if (!item[this.config.label]){
								continue;
							}
							label = item[this.config.label];
							value = item[this.config.value];
						}
						if (this.customLabel) {
							label = this.customLabel(item);
						}
						options.push({
							label: label,
							value: value
						});						
						if (label == this.currentKeyword) {
							foundItem = true;
							foundValue = value;
						}
					}
					this.noItemFound = !foundItem;
					this.currentOptions = options;
					if (keyword == this.value) {
						this.noItemFound = false;
					}
					this.$emit('options', options);
					if (setCurrentItem && foundValue) {
						let vm = this;
						// 等待options成功绑定后再绑定value
						Vue.nextTick(function() {
							vm.setItem(foundValue);
						});
						// this.setItem(foundValue);
					}
				}
				else {
					vm.$message.error('选项加载失败，请稍后重试');
				}
			},
			onAdd() {
				let addingKeyword = this.currentKeyword;
				let data = {};
				data[this.config.addParam] = addingKeyword;
				this.adding = true;
				let vm = this;
				ModelUtils.buildQueryExtraParams(this.config, this.paramsData, data);
				request(this.config.url, this.config.addMethod, data, this.config.transfer, function(res) {
					vm.adding = false;
					if (typeof (res) == 'string') {
						res = JSON.parse(res);
					}
					if (!Array.isArray(res)) {
						let array = [];
						array.push(res);
						res = array;
					}
					vm.setQueryResult(addingKeyword, res, true);
					vm.added = true;
					vm.$message.success('已将"' + addingKeyword + '" 收录到数据库');
				}, function(error) {
					vm.adding = false;
					console.log(error);
					vm.$message.error('添加选项失败，请稍后重试');
				});
			}
		},
		mounted() {
			this.doQuery();
		}
	}
</script>